home *** CD-ROM | disk | FTP | other *** search
- /* $VER: lib.c 2.0 (6.4.2002) by Grzegorz Kraszewski */
-
- /****** ttrender.library/background *****************************************
- *
- *
- * PURPOSE
- *
- * The library is fast, AmigaOS friendly TrueType render engine. It has
- * nothing to do with Amiga outline font system. This system has a lot of
- * limitations which make it useless for high speed and quality text output.
- * If someone wants an integration of TrueType with AmigaOS bullet.library
- * like outline font system, should consider using ttf.library. This library
- * opens TrueType font by itself and renders high quality glyphs directly
- * into any RastPort.
- *
- * FREETYPE2 BASED
- *
- * The render engine of the library is based on FreeType2 project
- * (http://www.freetype.org). This version of ttrender.library uses 2.0.9
- * FreeType build.
- *
- * REQUIREMENTS
- *
- * The library requires at least CyberGraphX 3.x or Picasso96 2.x system. It
- * is possible that non-antialiased output will be possible on AGA machines
- * in the future.
- *
- * FEATURES
- *
- * The library expands FreeType functionality making usage of TrueType fonts
- * easy and comfortable. Below you can find key features:
- *
- * - renders whole strings (not single glyphs) with kerning.
- * - antialiasing to any (not neccesarily uniform color) background.
- * - system compatible output to any (including planar) RastPort.
- * - supports JAM1. JAM2, INVERSVID, COMPLEMENT RastPort modes.
- * - supports 8-bit to Unicode mapping with "ENV:ttfcodepage" table
- * compatible with ttf.library.
- * - allows for direct 16-bit Unicode string rendering.
- * - easy to use, taglist based API.
- * - efficient system-wide glyph cache system.
- *
- * CACHE SYSTEM
- *
- * The library uses my own (not that experimental FreeType one) cache system
- * speeding up strings rendering alot. The cache is system-wide, it means it
- * is common to every application using ttrender.library. Only used glyphs of
- * given font face are cached. If the library encounters cache miss, missing
- * glyph is loaded and rasterized on the fly. Cache system is totally
- * transparent to the library user, so there are no cache functions in the
- * library API. Cache uses one single Exec memory pool avoiding memory
- * fragmentation.
- *
- * FONT DIRECTORIES
- *
- * The library searches for a font in three directories:
- * 1. Process current directory.
- * 2. "PROGDIR:" of the calling application.
- * 3. "FONTS:_TrueType_Outlines" as a common location for TrueType fonts.
- *
- *****************************************************************************
- *
- */
-
- #define __NOLIBBASE__
-
- #include <ft2build.h>
- #include FT_FREETYPE_H
-
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/expansion.h>
- #include <proto/utility.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <proto/cybergraphics.h>
- #include <exec/libraries.h>
- #include <exec/resident.h>
- #include <exec/memory.h>
- #include <cybergraphx/cybergraphics.h>
- #include <string.h>
-
- #define reg(a) __asm(#a)
- #define USELIB(a) struct Library *##a = ttb->ttb_##a
- #define MAX_PATH_LENGHT 1024 /* maximum length of file path including ending zero */
-
- #include "lib.h"
-
- struct TTRenderBase *Ttb;
- struct Library *__UtilityBase; /* required for libnix 64-bit arithmetic */
-
-
- /*--- Functions prototypes -------------------------------------------------*/
-
- struct TTRenderBase *LibInit(void *seglist reg(a0), struct Library *sysb reg(a6));
- struct TTRenderBase *LibOpen(struct TTRenderBase *ttb reg(a6));
- LONG LibClose(struct TTRenderBase *ttb reg(a6));
- APTR LibExpunge(struct TTRenderBase *ttb reg(a6));
- LONG LibReserved(void);
- BOOL TT_SetFont(struct TTRenderBase *ttb reg(a6), STRPTR name reg(a0), UWORD size reg(d0));
- BOOL TT_PutStr(struct TTRenderBase *ttb reg(a6), UBYTE *str reg(a0));
- BOOL TT_PutUStr(struct TTRenderBase *ttb reg(a6), UWORD *str reg(a0));
- BOOL TT_PutStrTagList(struct TTRenderBase *ttb reg(a6), UBYTE *str reg(a0), struct TagItem *taglist reg(a1));
- BOOL TT_PutUStrTagList(struct TTRenderBase *ttb reg(a6), UWORD *str reg(a0), struct TagItem *taglist reg(a1));
- ULONG TT_SetModesTagList(struct TTRenderBase *ttb reg(a6), struct TagItem *taglist reg(a0));
- ULONG TT_GetFontAttrsTagList(struct TTRenderBase *ttb reg(a6), struct TagItem *taglist reg(a0));
- ULONG TT_StrWidth(struct TTRenderBase *ttb reg(a6), UBYTE *string reg(a0));
- ULONG TT_UStrWidth(struct TTRenderBase *ttb reg(a6), UWORD *string reg(a0));
-
- extern struct Resident romtag;
-
- /* cached one glyph bitmap */
-
- struct CachedBitmap
- {
- struct MinNode cb_Node;
- LONG cb_AdvanceX;
- LONG cb_AdvanceY;
- WORD cb_OffsetX;
- WORD cb_OffsetY;
- FT_Bitmap cb_Bitmap;
- ULONG cb_Index;
- };
-
- /* cached typeface of given size */
-
- struct CachedSize
- {
- struct MinNode cs_Node;
- UWORD cs_PixelSize;
- struct MinList cs_Bitmaps; /* list of CachedBitmap structures */
- };
-
- /* cached multiple sizes of one face */
-
- struct CachedFont
- {
- struct MinNode cf_Node;
- char *cf_Name;
- struct MinList cf_Sizes; /* list of CachedSize structures */
- };
-
- /* memory cache functions declarations */
-
- struct CachedBitmap *cache_add_bitmap(struct TTRenderBase *ttb, struct CachedSize *cs,
- FT_GlyphSlot glyph, ULONG index);
- struct CachedBitmap *cache_find_bitmap(struct TTRenderBase *ttb, struct CachedSize *cs,
- ULONG index, char mode);
- void cache_flush_bitmap(struct TTRenderBase *ttb, struct CachedBitmap *cb);
-
- struct CachedSize *cache_add_size(struct TTRenderBase *ttb, struct CachedFont *cf, UWORD size);
- struct CachedSize *cache_find_size(struct TTRenderBase *ttb, struct CachedFont *cf, UWORD size);
- void cache_flush_size(struct TTRenderBase *ttb, struct CachedSize *cs);
-
- struct CachedFont *cache_add_font(struct TTRenderBase *ttb, char *name);
- struct CachedFont *cache_find_font(struct TTRenderBase *ttb, char *name);
- void cache_flush_font(struct TTRenderBase *ttb, struct CachedFont *cf);
-
- void cache_flush_all(struct TTRenderBase *ttb);
-
- /* codepage handling functions prototypes */
-
- static void load_codepage(struct TTRenderBase *ttb);
- static void free_codepage(struct TTRenderBase *ttb);
-
- /* === CODE STARTS HERE === */
-
- /*--------------------------------------------------------------------------*/
-
- static const void *FuncTable[] =
- {
- LibOpen,
- LibClose,
- LibExpunge,
- LibReserved,
- TT_PutStr,
- TT_PutUStr,
- TT_SetFont,
- TT_PutStrTagList,
- TT_PutUStrTagList,
- TT_SetModesTagList,
- TT_GetFontAttrsTagList,
- TT_StrWidth,
- TT_UStrWidth,
- (APTR)-1
- };
-
-
- /*----------------------------------------------------------------------------------------------------*/
-
- static void get_rp_fgcolor(struct TTRenderBase *ttb, struct RastPort *rp, struct ColorMap *cm,
- UBYTE *dest)
- {
- USELIB(GfxBase);
-
- ULONG tcolor[3];
- WORD i;
-
- GetRGB32(cm, GetAPen(rp), 1, tcolor);
- for (i = 0; i < 3; i++) dest[i] = tcolor[i] >> 24;
- }
-
- /*----------------------------------------------------------------------------------------------------*/
-
- /*static void get_rp_bgcolor(struct TTRenderBase *ttb, struct RastPort *rp, struct ColorMap *cm,
- UBYTE *dest)
- {
- USELIB(GfxBase);
-
- ULONG tcolor[3];
- WORD i;
-
- GetRGB32(cm, GetBPen(rp), 1, tcolor);
- for (i = 0; i < 3; i++) dest[i] = tcolor[i] >> 24;
- }*/
-
- /*----------------------------------------------------------------------------------------------------*/
-
- static void blt_gray_bitmap(struct TTRenderBase *ttb, FT_Bitmap *bm, struct RastPort *rp,
- struct ColorMap *cm, WORD dstx, WORD dsty)
- {
- USELIB(GfxBase);
- USELIB(CyberGfxBase);
- USELIB(SysBase);
-
- ULONG bufsize, drawmode;
- UBYTE *buf;
- UBYTE fgcolor[3], bgcolor[3];
-
- drawmode = GetDrMd(rp);
- get_rp_fgcolor(ttb, rp, cm, fgcolor);
-
- bufsize = bm->width * bm->rows * sizeof(ULONG);
-
- if (buf = AllocPooled(ttb->ttb_MemPool, bufsize))
- {
- WORD xi, yi;
- UBYTE *ptr = buf, *src = bm->buffer;
-
- ReadPixelArray(buf, 0, 0, bm->width * sizeof(ULONG), rp, dstx, dsty, bm->width, bm->rows,
- RECTFMT_ARGB);
-
- for (yi = 0; yi < bm->rows; yi++)
- {
- for (xi = 0; xi < bm->width; xi++)
- {
- UBYTE alpha;
-
- *ptr++ = 0;
- alpha = (drawmode & INVERSVID) ? ~src[xi] : src[xi];
-
- *ptr += ((WORD)(fgcolor[0] - *ptr++) * (WORD)(alpha)) >> 8;
- *ptr += ((WORD)(fgcolor[1] - *ptr++) * (WORD)(alpha)) >> 8;
- *ptr += ((WORD)(fgcolor[2] - *ptr++) * (WORD)(alpha)) >> 8;
- }
- src += bm->pitch;
- }
-
- WritePixelArray(buf, 0, 0, bm->width * sizeof(ULONG), rp, dstx, dsty, bm->width, bm->rows,
- RECTFMT_ARGB);
-
- FreePooled(ttb->ttb_MemPool, buf, bufsize);
- }
- }
-
-
- /*----------------------------------------------------------------------------------------------------*/
-
- static void blt_mono_bitmap(struct TTRenderBase *ttb, FT_Bitmap *bm, struct RastPort *rp,
- struct ColorMap *cm, WORD dstx, WORD dsty)
- {
- USELIB(GfxBase);
- USELIB(CyberGfxBase);
- USELIB(SysBase);
-
- ULONG bufsize, drawmode;
- UBYTE *buf;
- UBYTE fgcolor[3], bgcolor[3];
-
- drawmode = GetDrMd(rp);
- get_rp_fgcolor(ttb, rp, cm, fgcolor);
-
- bufsize = bm->width * bm->rows * sizeof(ULONG);
-
- if (buf = AllocPooled(ttb->ttb_MemPool, bufsize))
- {
- WORD xi, yi;
- UBYTE *ptr = buf, *src = bm->buffer;
-
- ReadPixelArray(buf, 0, 0, bm->width * sizeof(ULONG), rp, dstx, dsty, bm->width, bm->rows,
- RECTFMT_ARGB);
-
- for (yi = 0; yi < bm->rows; yi++)
- {
- for (xi = 0; xi < bm->width; xi++)
- {
- UBYTE b, mask;
-
- if (!(xi & 7))
- {
- mask = 0x80;
- b = src[xi >> 3];
- }
- else mask >>= 1;
-
- *ptr++ = 0;
- if (b & mask)
- {
- *ptr++ = fgcolor[0];
- *ptr++ = fgcolor[1];
- *ptr++ = fgcolor[2];
- }
- else ptr += 3;
- }
- src += bm->pitch;
- }
-
- WritePixelArray(buf, 0, 0, bm->width * sizeof(ULONG), rp, dstx, dsty, bm->width, bm->rows,
- RECTFMT_ARGB);
-
- FreePooled(ttb->ttb_MemPool, buf, bufsize);
- }
- }
-
- /*----------------------------------------------------------------------------------------------------*/
-
- ULONG tt_strwidth(struct TTRenderBase *ttb, struct RenderEnv *re, APTR str, BOOL unicode)
- {
- USELIB(DOSBase);
-
- ULONG chindex = 0, previous;
- ULONG xpos = 0, ypos = 0;
- int error;
- UBYTE *nstr = str;
- UWORD *ustr = str;
- UWORD chcode;
- struct CachedBitmap *cb;
- FT_Face face = ttb->ttb_Face;
- BOOL use_kerning = FT_HAS_KERNING(face);
-
- struct RastPort *rp = re->re_TargetRPort;
- struct ColorMap *cm = re->re_TargetCMap;
- char render_mode = re->re_Antialias ? 0 : ft_render_mode_mono;
- char bitmap_mode = re->re_Antialias ? ft_pixel_mode_grays : ft_pixel_mode_mono;
-
- while (chcode = unicode ? *ustr++ : *nstr++)
- {
- previous = chindex;
- if (!unicode && ttb->ttb_CodePage) chcode = ttb->ttb_CodePage[chcode];
-
- chindex = FT_Get_Char_Index(face, chcode);
-
-
- if (previous && use_kerning)
- {
- FT_Vector delta;
-
- FT_Get_Kerning(face, previous, chindex, ft_kerning_unfitted, &delta);
- xpos += delta.x;
- }
-
- if (cb = cache_find_bitmap(ttb->ttb_RealTTRenderBase, ttb->ttb_CurrentCache,
- chindex, bitmap_mode))
- {
- DBG("MemCache HIT");
-
- xpos += cb->cb_AdvanceX;
- ypos += cb->cb_AdvanceY;
- }
- else
- {
- DBG("MemCache MISS");
-
- if (!FT_Load_Glyph(face, chindex, 0))
- {
- if (!(error = FT_Render_Glyph(face->glyph, render_mode)))
- {
- FT_Bitmap *bm = &(face->glyph->bitmap);
-
- cache_add_bitmap(ttb->ttb_RealTTRenderBase, ttb->ttb_CurrentCache,
- face->glyph, chindex);
- }
- }
- xpos += face->glyph->advance.x;
- ypos += face->glyph->advance.y;
- }
- }
- return ((xpos + 32) >> 6);
- }
-
-
- void tt_putstr(struct TTRenderBase *ttb, struct RenderEnv *re, WORD x, WORD y,
- APTR str, BOOL unicode)
- {
- USELIB_DBG(DOSBase)
- // USELIB(DOSBase);
- USELIB(GfxBase);
-
- ULONG chindex = 0, previous;
- ULONG xpos = x << 6, ypos = y << 6;
- int error;
- UBYTE *nstr = str;
- UWORD *ustr = str;
- UWORD chcode;
- struct CachedBitmap *cb;
- FT_Face face = ttb->ttb_Face;
- BOOL use_kerning = FT_HAS_KERNING(face);
- UWORD pixlen;
-
- struct RastPort *rp = re->re_TargetRPort;
- struct ColorMap *cm = re->re_TargetCMap;
- char render_mode = re->re_Antialias ? 0 : ft_render_mode_mono;
- char bitmap_mode = re->re_Antialias ? ft_pixel_mode_grays : ft_pixel_mode_mono;
-
- pixlen = tt_strwidth(ttb, re, str, unicode);
-
- /* draw backgorund in JAM2 mode */
-
- if (GetDrMd(rp) & JAM2)
- {
- ULONG old_fg_pen = GetAPen(rp);
-
- SetAPen(rp, GetBPen(rp));
- RectFill(rp, rp->cp_x, rp->cp_y - ttb->ttb_Ascender, rp->cp_x + pixlen,
- rp->cp_y + ttb->ttb_Descender);
- SetAPen(rp, old_fg_pen);
- }
-
- while (chcode = unicode ? *ustr++ : *nstr++)
- {
- previous = chindex;
- if (!unicode && ttb->ttb_CodePage) chcode = ttb->ttb_CodePage[chcode];
-
- chindex = FT_Get_Char_Index(face, chcode);
-
-
- if (previous && use_kerning)
- {
- FT_Vector delta;
-
- FT_Get_Kerning(face, previous, chindex, ft_kerning_unfitted, &delta);
- xpos += delta.x;
- }
-
- /* glyph already cached with tt_strwidth() */
-
- cb = cache_find_bitmap(ttb->ttb_RealTTRenderBase, ttb->ttb_CurrentCache,
- chindex, bitmap_mode);
-
- switch (cb->cb_Bitmap.pixel_mode)
- {
- case ft_pixel_mode_grays:
- blt_gray_bitmap(ttb, &cb->cb_Bitmap, rp, cm, (xpos >> 6) + cb->cb_OffsetX,
- (ypos >> 6) - cb->cb_OffsetY);
- break;
-
- case ft_pixel_mode_mono:
- blt_mono_bitmap(ttb, &cb->cb_Bitmap, rp, cm, (xpos >> 6) + cb->cb_OffsetX,
- (ypos >> 6) - cb->cb_OffsetY);
- break;
- }
- xpos += cb->cb_AdvanceX;
- ypos += cb->cb_AdvanceY;
- }
- }
-
- /*----------------------------------------------------------------------------------------------------*/
- /* always gets "real" TTRenderBase */
-
- struct CachedBitmap *cache_add_bitmap(struct TTRenderBase *ttb, struct CachedSize *cs,
- FT_GlyphSlot glyph, ULONG index)
- {
- USELIB(SysBase);
- USELIB_DBG(DOSBase)
-
- struct CachedBitmap *cb;
- ULONG bmsize;
-
- if (cb = AllocPooled(ttb->ttb_MemPool, sizeof(struct CachedBitmap)))
- {
- cb->cb_Index = index;
- cb->cb_AdvanceX = glyph->advance.x;
- cb->cb_AdvanceY = glyph->advance.y;
- cb->cb_OffsetX = glyph->bitmap_left;
- cb->cb_OffsetY = glyph->bitmap_top;
- CopyMem(&glyph->bitmap, &cb->cb_Bitmap, sizeof(FT_Bitmap));
- bmsize = cb->cb_Bitmap.rows * cb->cb_Bitmap.pitch;
-
- if (bmsize)
- {
- if (cb->cb_Bitmap.buffer = AllocPooled(ttb->ttb_MemPool, bmsize))
- {
- CopyMem(glyph->bitmap.buffer, cb->cb_Bitmap.buffer, bmsize);
- }
- }
- else cb->cb_Bitmap.buffer = NULL;
-
- if (cb->cb_Bitmap.buffer || !bmsize)
- {
- ttb->ttb_MemCacheSize += sizeof(struct CachedBitmap) + bmsize;
- AddTail((struct List*)&cs->cs_Bitmaps, (struct Node*)cb);
-
- DBG2("\tMemCache: %ld glyph added, cache size %ld bytes.", cb->cb_Index,
- ttb->ttb_MemCacheSize);
- return cb;
- }
- FreePooled(ttb->ttb_MemPool, cb, sizeof(struct CachedBitmap));
- }
- return NULL;
- }
-
- /*----------------------------------------------------------------------------------------------------*/
- /* always gets "real" TTRenderBase */
-
- struct CachedBitmap *cache_find_bitmap(struct TTRenderBase *ttb, struct CachedSize *cs, ULONG index,
- char mode)
- {
- struct MinNode *n;
-
- for(n = cs->cs_Bitmaps.mlh_Head; n->mln_Succ; n = n->mln_Succ)
- {
- if (((struct CachedBitmap*)n)->cb_Index == index &&
- ((struct CachedBitmap*)n)->cb_Bitmap.pixel_mode == mode) return (struct CachedBitmap*)n;
- }
- return NULL;
- }
-
- /*----------------------------------------------------------------------------------------------------*/
- /* always gets "real" TTRenderBase */
-
- void cache_flush_bitmap(struct TTRenderBase *ttb, struct CachedBitmap *cb)
- {
- USELIB(SysBase);
- USELIB_DBG(DOSBase)
- ULONG bsize;
-
- DBG1("\t\tMemCache: '%ld' bitmap flushed.", cb->cb_Index);
-
- bsize = cb->cb_Bitmap.rows * cb->cb_Bitmap.pitch;
- Remove((struct Node*)cb);
-
- if (cb->cb_Bitmap.buffer) FreePooled(ttb->ttb_MemPool, cb->cb_Bitmap.buffer, bsize);
- FreePooled(ttb->ttb_MemPool, cb, sizeof(struct CachedBitmap));
- ttb->ttb_MemCacheSize -= sizeof(struct CachedBitmap) + bsize;
-
- DBG1("\t\tCache size %ld bytes.", ttb->ttb_MemCacheSize);
- }
-
- /*----------------------------------------------------------------------------------------------------*/
- /* always gets "real" TTRenderBase */
-
- struct CachedSize *cache_add_size(struct TTRenderBase *ttb, struct CachedFont *cf, UWORD size)
- {
- USELIB(SysBase);
- USELIB_DBG(DOSBase)
-
- struct CachedSize *cs;
-
- if (cs = AllocPooled(ttb->ttb_MemPool, sizeof(struct CachedSize)))
- {
- cs->cs_PixelSize = size;
- cs->cs_Bitmaps.mlh_Head = (struct MinNode*)&cs->cs_Bitmaps.mlh_Tail;
- cs->cs_Bitmaps.mlh_Tail = NULL;
- cs->cs_Bitmaps.mlh_TailPred = (struct MinNode*)&cs->cs_Bitmaps.mlh_Head;
- ttb->ttb_MemCacheSize += sizeof(struct CachedSize);
- AddTail((struct List*)&cf->cf_Sizes, (struct Node*)cs);
-
- DBG2("\tMemCache: %ld size added, cache size %ld bytes.", cs->cs_PixelSize,
- ttb->ttb_MemCacheSize);
- return cs;
- }
- return NULL;
- }
-
- /*----------------------------------------------------------------------------------------------------*/
- /* always gets "real" TTRenderBase */
-
- struct CachedSize *cache_find_size(struct TTRenderBase *ttb, struct CachedFont *cf, UWORD size)
- {
- struct MinNode *n;
-
- for(n = cf->cf_Sizes.mlh_Head; n->mln_Succ; n = n->mln_Succ)
- {
- if (((struct CachedSize*)n)->cs_PixelSize == size) return (struct CachedSize*)n;
- }
- return NULL;
- }
-
- /*----------------------------------------------------------------------------------------------------*/
- /* always gets "real" TTRenderBase */
-
- void cache_flush_size(struct TTRenderBase *ttb, struct CachedSize *cs)
- {
- USELIB(SysBase);
- USELIB_DBG(DOSBase)
-
- struct MinNode *n, *n2;
-
- DBG1("\tMemCache: '%ld' size flushed.", cs->cs_PixelSize);
-
- Remove((struct Node*)cs);
-
- n = cs->cs_Bitmaps.mlh_Head;
- while(n2 = n->mln_Succ)
- {
- cache_flush_bitmap(ttb, (struct CachedBitmap*)n);
- n = n2;
- }
-
- FreePooled(ttb->ttb_MemPool, cs, sizeof(struct CachedSize));
- ttb->ttb_MemCacheSize -= sizeof(struct CachedSize);
-
- DBG1("\tCache size %ld bytes.", ttb->ttb_MemCacheSize);
- }
-
- /*----------------------------------------------------------------------------------------------------*/
- /* always gets "real" TTRenderBase */
-
- struct CachedFont *cache_add_font(struct TTRenderBase *ttb, char *name)
- {
- USELIB(SysBase);
- USELIB_DBG(DOSBase)
-
- struct CachedFont *cf;
- ULONG namelen;
-
- namelen = strlen(name) + 1;
-
- if (cf = AllocPooled(ttb->ttb_MemPool, sizeof(struct CachedFont)))
- {
- if (cf->cf_Name = AllocPooled(ttb->ttb_MemPool, namelen))
- {
- strcpy(cf->cf_Name, name);
- cf->cf_Sizes.mlh_Head = (struct MinNode*)&cf->cf_Sizes.mlh_Tail;
- cf->cf_Sizes.mlh_Tail = NULL;
- cf->cf_Sizes.mlh_TailPred = (struct MinNode*)&cf->cf_Sizes.mlh_Head;
- ttb->ttb_MemCacheSize += sizeof(struct CachedFont) + namelen;
- AddTail((struct List*)&ttb->ttb_MemoryCache, (struct Node*)cf);
-
- DBG2("\tMemCache: '%s' font added, cache size %ld bytes.", (LONG)cf->cf_Name,
- ttb->ttb_MemCacheSize);
- return cf;
- }
- FreePooled(ttb->ttb_MemPool, cf, sizeof(struct CachedFont));
- }
- return NULL;
- }
-
- /*----------------------------------------------------------------------------------------------------*/
- /* always gets "real" TTRenderBase */
-
- void cache_flush_font(struct TTRenderBase *ttb, struct CachedFont *cf)
- {
- USELIB(SysBase);
- USELIB_DBG(DOSBase)
-
- struct MinNode *n, *n2;
- ULONG namelen;
-
- namelen = strlen(cf->cf_Name) + 1;
-
- DBG1("\tMemCache: '%s' font flushed.", (LONG)cf->cf_Name);
-
- Remove((struct Node*)cf);
-
- n = cf->cf_Sizes.mlh_Head;
- while(n2 = n->mln_Succ)
- {
- cache_flush_size(ttb, (struct CachedSize*)n);
- n = n2;
- }
-
- FreePooled(ttb->ttb_MemPool, cf->cf_Name, namelen);
- FreePooled(ttb->ttb_MemPool, cf, sizeof(struct CachedFont));
- ttb->ttb_MemCacheSize -= namelen + sizeof(struct CachedFont);
-
- DBG1("\tCache size %ld bytes.", ttb->ttb_MemCacheSize);
- }
-
- /*----------------------------------------------------------------------------------------------------*/
- /* always gets "real" TTRenderBase */
-
- struct CachedFont *cache_find_font(struct TTRenderBase *ttb, char *name)
- {
- struct MinNode *n;
-
- for(n = ttb->ttb_MemoryCache.mlh_Head; n->mln_Succ; n = n->mln_Succ)
- {
- if (strcmp(((struct CachedFont*)n)->cf_Name, name) == 0) return (struct CachedFont*)n;
- }
- return NULL;
- }
-
- /*----------------------------------------------------------------------------------------------------*/
- /* always gets "real" TTRenderBase */
-
- void cache_flush_all(struct TTRenderBase *ttb)
- {
- struct MinNode *n, *n2;
-
- n = ttb->ttb_MemoryCache.mlh_Head;
- while(n2 = n->mln_Succ)
- {
- cache_flush_font(ttb, (struct CachedFont*)n);
- n = n2;
- }
- }
-
- /*----------------------------------------------------------------------------------------------------*/
-
- static void load_codepage(struct TTRenderBase *ttb)
- {
- struct Library *SysBase = ttb->ttb_SysBase;
- struct Library *DOSBase = ttb->ttb_DOSBase;
- BPTR codepage;
- int d;
-
- /* load codepage */
-
- ttb->ttb_CodePage = NULL;
-
- if (codepage = Open("ENV:ttfcodepage", MODE_OLDFILE))
- {
- if (ttb->ttb_CodePage = AllocPooled(ttb->ttb_MemPool, 512))
- {
- if (Read(codepage, ttb->ttb_CodePage, 512) != 512)
- {
- FreePooled(ttb->ttb_MemPool, ttb->ttb_CodePage, 512);
- ttb->ttb_CodePage = NULL;
- }
- }
- Close(codepage);
- }
- }
-
- /*----------------------------------------------------------------------------------------------------*/
-
- static void free_codepage(struct TTRenderBase *ttb)
- {
- USELIB(SysBase);
-
- if (ttb->ttb_CodePage) FreePooled(ttb->ttb_MemPool, ttb->ttb_CodePage, 512);
- }
-
- /*-------------------------------------------------------------------------*/
- /* INIT */
- /*-------------------------------------------------------------------------*/
-
- __saveds struct TTRenderBase *LibInit (APTR seglist reg(a0),
- struct Library *sysb reg(a6))
- {
- struct TTRenderBase *ttb, *rval = NULL;
- struct Library *SysBase = sysb;
-
- if (ttb = (struct TTRenderBase*)MakeLibrary (FuncTable, NULL, NULL,
- sizeof (struct TTRenderBase), 0))
- {
- ttb->ttb_Lib.lib_Node.ln_Type = NT_LIBRARY;
- ttb->ttb_Lib.lib_Node.ln_Name = romtag.rt_Name;
- ttb->ttb_Lib.lib_Flags = LIBF_CHANGED | LIBF_SUMUSED;
- ttb->ttb_Lib.lib_Version = 2;
- ttb->ttb_Lib.lib_Revision = 0;
- ttb->ttb_Lib.lib_IdString = romtag.rt_IdString;
- ttb->ttb_Lib.lib_OpenCnt = 0;
- ttb->ttb_SegList = seglist;
- ttb->ttb_SysBase = SysBase;
- ttb->ttb_MemPool = NULL;
- ttb->ttb_RealTTRenderBase = NULL;
- ttb->ttb_RenderEnv.re_TargetRPort = NULL;
- ttb->ttb_RenderEnv.re_TargetCMap = NULL;
- ttb->ttb_RenderEnv.re_Antialias = FALSE;
- ttb->ttb_GfxBase = NULL;
- ttb->ttb_DOSBase = NULL;
- ttb->ttb_CyberGfxBase = NULL;
- ttb->ttb_UtilityBase = NULL;
- ttb->ttb_FTLib = NULL;
- ttb->ttb_Face = NULL;
- ttb->ttb_MemoryCache.mlh_Head = (struct MinNode*)&ttb->ttb_MemoryCache.mlh_Tail;
- ttb->ttb_MemoryCache.mlh_Tail = NULL;
- ttb->ttb_MemoryCache.mlh_TailPred = (struct MinNode*)&ttb->ttb_MemoryCache.mlh_Head;
- ttb->ttb_MemCacheSize = 0;
- ttb->ttb_Ascender = 0;
- ttb->ttb_Descender = 0;
- AddLibrary ((struct Library*)ttb);
- rval = ttb;
- }
- return rval;
- }
-
-
- /*-------------------------------------------------------------------------*/
- /* OPEN */
- /*-------------------------------------------------------------------------*/
-
- static struct TTRenderBase *init_resources(struct TTRenderBase *ttb)
- {
- USELIB(SysBase);
- USELIB_DBG(DOSBase)
- LONG ft_error;
-
- if (!(__UtilityBase = OpenLibrary("utility.library", 39))) return NULL;
- ttb->ttb_UtilityBase = __UtilityBase;
- if (!(ttb->ttb_GfxBase = OpenLibrary("graphics.library", 39))) return NULL;
- if (!(ttb->ttb_DOSBase = OpenLibrary("dos.library", 38))) return NULL;
- if (!(ttb->ttb_CyberGfxBase = OpenLibrary("cybergraphics.library", 41))) return NULL;
- if (!(ttb->ttb_MemPool = CreatePool(MEMF_ANY | MEMF_CLEAR, 1024, 512))) return NULL;
-
- #ifdef TTR_DEBUG
- DOSBase = ttb->ttb_DOSBase;
- ttb->debug = Open("KCON:0/17/640/150/ttrender.library/AUTO/CLOSE", MODE_NEWFILE);
- #endif
-
- load_codepage(ttb);
-
- Ttb = ttb;
-
- if (ft_error = FT_Init_FreeType(&ttb->ttb_FTLib) != 0)
- {
- DBG1("FT_Init_FreeType() failed, error %ld.", ft_error);
- ttb->ttb_FTLib = NULL;
- return NULL;
- }
- DBG("Library initialization successfull.");
- return ttb;
- }
-
-
- /* always gets "real" TTRenderBase */
-
- static void free_resources(struct TTRenderBase *ttb)
- {
- USELIB(SysBase);
-
- if (ttb->ttb_FTLib) FT_Done_FreeType(ttb->ttb_FTLib);
- if (ttb->ttb_CyberGfxBase) CloseLibrary(ttb->ttb_CyberGfxBase);
- if (ttb->ttb_DOSBase) CloseLibrary(ttb->ttb_DOSBase);
- if (ttb->ttb_GfxBase) CloseLibrary(ttb->ttb_GfxBase);
- if (__UtilityBase) CloseLibrary(__UtilityBase);
- cache_flush_all(ttb);
- free_codepage(ttb);
- if (ttb->ttb_MemPool) DeletePool(ttb->ttb_MemPool);
- return;
- }
-
-
- __saveds struct TTRenderBase *LibOpen (struct TTRenderBase *ttb_real reg(a6))
- {
- struct TTRenderBase *ttb_fake = NULL;
- struct Library *SysBase = ttb_real->ttb_SysBase;
-
- if (ttb_fake = (struct TTRenderBase*)MakeLibrary (FuncTable, NULL, NULL,
- sizeof (struct TTRenderBase), 0))
- {
- if (!ttb_real->ttb_MemPool)
- {
- if (!init_resources(ttb_real))
- {
- free_resources(ttb_real);
- FreeMem ((APTR)ttb_fake - ttb_fake->ttb_Lib.lib_NegSize,
- (LONG)ttb_fake->ttb_Lib.lib_PosSize + (LONG)ttb_fake->ttb_Lib.lib_NegSize);
- return NULL;
- }
- }
-
- CopyMem((APTR)ttb_real, (APTR)ttb_fake, sizeof(struct TTRenderBase));
- ttb_fake->ttb_RealTTRenderBase = ttb_real;
- {
- #ifdef TTR_DEBUG
- struct Library *DOSBase = ttb_fake->ttb_DOSBase;
- #endif
-
- DBG2("Library opened, real base $%08lx, priv base $%08lx.", (LONG)ttb_real, (LONG)ttb_fake);
- }
- ttb_real->ttb_Lib.lib_OpenCnt++;
- ttb_real->ttb_Lib.lib_Flags &= ~LIBF_DELEXP;
- return ttb_fake;
- }
- }
-
- /*-------------------------------------------------------------------------*/
- /* CLOSE */
- /*-------------------------------------------------------------------------*/
-
- __saveds long LibClose(struct TTRenderBase *ttb_fake reg(a6))
- {
- struct Library *SysBase = ttb_fake->ttb_SysBase;
- struct TTRenderBase *ttb_real = ttb_fake->ttb_RealTTRenderBase;
-
- #ifdef TTR_DEBUG
- struct Library *DOSBase = ttb_fake->ttb_DOSBase;
- #endif
-
- if (ttb_fake->ttb_Face) FT_Done_Face(ttb_fake->ttb_Face);
- FreeMem ((APTR)ttb_fake - ttb_fake->ttb_Lib.lib_NegSize,
- (LONG)ttb_fake->ttb_Lib.lib_PosSize + (LONG)ttb_fake->ttb_Lib.lib_NegSize);
-
- DBG("Library closed");
- if (!(--ttb_real->ttb_Lib.lib_OpenCnt))
- {
- if (ttb_real->ttb_Lib.lib_Flags & LIBF_DELEXP) return ((long)LibExpunge(ttb_real));
- }
- return 0;
- }
-
- /*-------------------------------------------------------------------------*/
- /* EXPUNGE */
- /*-------------------------------------------------------------------------*/
-
- __saveds APTR LibExpunge (struct TTRenderBase *ttb reg(a6))
- {
- USELIB(SysBase);
- APTR seglist;
-
- if (ttb->ttb_Lib.lib_OpenCnt)
- {
- ttb->ttb_Lib.lib_Flags |= LIBF_DELEXP;
- return 0;
- }
- Remove ((struct Node*)ttb);
- free_resources(ttb);
- seglist = ttb->ttb_SegList;
- FreeMem ((APTR)ttb - ttb->ttb_Lib.lib_NegSize, (LONG)ttb->ttb_Lib.lib_PosSize +
- (LONG)ttb->ttb_Lib.lib_NegSize);
- return seglist;
- }
-
- /*-------------------------------------------------------------------------*/
- /* RESERVED */
- /*-------------------------------------------------------------------------*/
-
- long LibReserved (void)
- {
- return 0;
- }
-
-
- /****** ttrender.library/TT_SetFont *****************************************
- *
- * NAME
- * TT_SetFont -- Opens TrueType font with given name and size.
- *
- * SYNOPSIS
- * success = TT_SetFont (name, size)
- * A0 D0:16
- *
- * BOOL TT_SetFont (STRPTR, UWORD);
- *
- * FUNCTION
- * Opens TrueType font file and sets current font size in pixels. Every
- * following call to TT_PutStr[Tags/TagList]() or
- * TT_PutUStr[Tags/TagList]() will use this font and size.
- *
- * INPUTS
- * name - pointer to a NULL terminated string containing font name.
- * ".ttf" suffix will be added automatically. Search order is
- * defined as follows:
- * 1. current directory
- * "<name>.ttf"
- * 2. PROGDIR:
- * "PROGDIR:<name>.ttf"
- * 3. "FONTS:_TrueType_Outlines" (by analogy to _Bullet_Outlines)
- * "FONTS:_TrueType_Outlines/<name>.ttf"
- * size - screen size of the font in pixels (to be exact - it is the
- * distance between baselines of two following lines of text
- * expressed in pixels).
- *
- * RESULT
- * success - TRUE if the font has been opened successfully, FALSE
- * otherwise. This function can fail for three reasons:
- * 1. File not found or malformed.
- * 2. Zero font size.
- * 3. No memory for requested (too big?) size.
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- * TT_PutStr(), TT_PutUStr()
- *
- *****************************************************************************
- *
- */
-
- __saveds BOOL TT_SetFont(struct TTRenderBase *ttb reg(a6), STRPTR name reg(a0), UWORD size reg(d0))
- {
- USELIB(SysBase);
- USELIB(DOSBase);
-
- STRPTR filepath;
- BOOL result = FALSE;
- BPTR testlock = 0;
- LONG error;
-
- struct CachedSize *cs;
- struct CachedFont *cf;
- struct RenderEnv *re = &ttb->ttb_RenderEnv;
-
- DBG2("TT_SetFont(\"%s\", %ld):", name, size);
-
- if (ttb->ttb_Face)
- {
- FT_Done_Face(ttb->ttb_Face);
- ttb->ttb_Face = NULL;
- }
-
- DBG("\tOld typeface cleared.");
-
- /* add .ttf suffix */
-
- if (filepath = AllocPooled(ttb->ttb_MemPool, MAX_PATH_LENGHT))
- {
- STRPTR p, q;
-
- strncpy(filepath, name, MAX_PATH_LENGHT - 8);
- strcat(filepath, ".ttf");
-
- /* OK, we have a full name, let's try current directory */
-
- DBG1("\tFont search: searching for \"%s\" file...", filepath);
-
- if (!(testlock = Lock(filepath, ACCESS_READ)))
- {
- /* Try "PROGDIR:" now */
-
- strcpy(filepath, "PROGDIR:");
- AddPart(filepath, name, MAX_PATH_LENGHT - 16);
- strcat(filepath, ".ttf");
- DBG1("\tFont search: searching for \"%s\" file...", filepath);
- if (!(testlock = Lock(filepath, ACCESS_READ)))
- {
- /* Still not found, try "FONTS:_TrueType_Outlines/" */
-
- strcpy(filepath, "FONTS:_TrueType_Outlines/");
- AddPart(filepath, name, MAX_PATH_LENGHT - 32);
- strcat(filepath, ".ttf");
- DBG1("\tFont search: searching for \"%s\" file...", filepath);
- if (!(testlock = Lock(filepath, ACCESS_READ)))
- {
- DBG("\tFont search: file not found.");
- result = FALSE;
- }
- }
- }
-
- if (testlock)
- {
- /* font file found, Tank, load us up :-) */
-
- DBG("\tFont file found, loading...");
- DBG1("\tFTLib = $%08lx.", ttb->ttb_FTLib);
- if (!(error = FT_New_Face(ttb->ttb_FTLib, filepath, 0, &ttb->ttb_Face)))
- {
- ULONG px_size, asc, desc;
-
- DBG1("\tFont face \"%s\" loaded succesfully.", name);
-
- /* compute correct pixel size for given height */
-
- px_size = ((size << 17) + (ttb->ttb_Face->height >> 1)) / ttb->ttb_Face->height;
- FT_Set_Char_Size(ttb->ttb_Face, 0, px_size,72, 72);
- DBG1("\tRescaled to %ld pixels height.", px_size);
-
- if (!(cf = cache_find_font(ttb->ttb_RealTTRenderBase, name)))
- cf = cache_add_font(ttb->ttb_RealTTRenderBase, name);
- if (cf)
- {
- if (!(cs = cache_find_size(ttb->ttb_RealTTRenderBase, cf, size)))
- cs = cache_add_size(ttb->ttb_RealTTRenderBase, cf, size);
- if (cs) ttb->ttb_CurrentCache = cs;
- }
-
- /* global metrics calculation */
-
- asc = (ttb->ttb_Face->size->metrics.ascender + 0x1F) >> 6;
- desc = (0x1F - ttb->ttb_Face->size->metrics.descender) >> 6;
- ttb->ttb_Ascender = asc + ((size - (asc + desc)) >> 1);
- ttb->ttb_Descender = size - ttb->ttb_Ascender;
-
- result = TRUE;
- }
- UnLock(testlock);
- }
- FreePooled(ttb->ttb_MemPool, filepath, MAX_PATH_LENGHT);
- }
- return result;
- }
-
- /****** ttrender.library/TT_PutStr ******************************************
- *
- * NAME
- * TT_PutStr -- Renders string into RastPort.
- *
- * SYNOPSIS
- * success = TT_PutStr (string)
- * A0
- *
- * BOOL TT_PutStr (UBYTE*);
- *
- * FUNCTION
- * Renders the string using current ttrender.library settings, and
- * current RastPort settings (pen, drawmode). String is rendered at
- * current RastPort (x, y) position, where 'y' means position of font
- * baseline. String is converted to Unicode according to
- * "ENV:ttfcodepage" mapping table. If there is no mapping table,
- * ISO-8859-1 mapping is used which is equal to ECMA Latin1 Amiga
- * standard.
- *
- * INPUTS
- * string - NULL-terminated string to render to.
- *
- * RESULT
- * TRUE if the string has been rendered.
- *
- * EXAMPLE
- * \* write a text with pen 1 and transp. background at (100, 100) *\
- * \* rendering is done to a system window *\
- *
- * SetAPen(win->RPort, 1);
- * SetDrMd(win->RPort, JAM1);
- * Move(win->RPort, 100, 100);
- * TT_SetModesTags(TTA_Window, win);
- * TT_PutStr("some text");
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- * TT_PutStrTagList(), TT_SetModesTagList(), TT_PutUStr()
- *
- *****************************************************************************
- *
- */
-
-
- __saveds BOOL TT_PutStr(struct TTRenderBase *ttb reg(a6), UBYTE *str reg(a0))
- {
- struct RenderEnv *re = &ttb->ttb_RenderEnv;
-
- if (re->re_TargetRPort && re->re_TargetCMap)
- {
- tt_putstr(ttb, re, re->re_TargetRPort->cp_x, re->re_TargetRPort->cp_y, str, FALSE);
- return TRUE;
- }
- return FALSE;
- }
-
- /****** ttrender.library/TT_PutUStr *****************************************
- *
- * NAME
- * TT_PutUStr -- Renders Unicode string into RastPort.
- *
- * SYNOPSIS
- * success = TT_PutUStr (string)
- * A0
- *
- * BOOL TT_PutUStr (UWORD*);
- *
- * FUNCTION
- * Renders the string using current ttrender.library (RastPort, ColorMap,
- * render mode), and RastPort settings (pen, drawmode). String is
- * rendered at current RastPort (x, y) position, where 'y' means position
- * of font baseline. String is an 16-bit Unicode one and should be
- * terminated with 16-bit zero.
- *
- * INPUTS
- * string - 16-bit Unicode NULL-terminated string to render to.
- *
- * RESULT
- * TRUE if the string has been rendered.
- *
- * BUGS
- *
- * SEE ALSO
- * TT_PutUStrTagList(), TT_SetModesTagList(), TT_PutStr()
- *
- *****************************************************************************
- *
- */
-
-
- __saveds BOOL TT_PutUStr(struct TTRenderBase *ttb reg(a6), UWORD *ustr reg(a0))
- {
- struct RenderEnv *re = &ttb->ttb_RenderEnv;
-
- if (re->re_TargetRPort && re->re_TargetCMap)
- {
- tt_putstr(ttb, re, re->re_TargetRPort->cp_x, re->re_TargetRPort->cp_y, ustr, TRUE);
- return TRUE;
- }
- return FALSE;
- }
-
-
- static ULONG parse_taglist(struct TTRenderBase *ttb, struct TagItem *taglist, struct RenderEnv *renv)
- {
- USELIB(UtilityBase);
- USELIB_DBG(DOSBase)
-
- struct TagItem *current_tag, *tag_pointer = taglist;
- BOOL rpset = FALSE, cmset = FALSE;
- ULONG tag_counter = 0;
-
- while (current_tag = NextTagItem(&tag_pointer))
- {
- switch (current_tag->ti_Tag)
- {
- case TTA_Antialias:
- renv->re_Antialias = current_tag->ti_Data;
- DBG1("\tAntialias %s", renv->re_Antialias ? (ULONG)"on" : (ULONG)"off");
- tag_counter++;
- break;
-
- case TTA_RastPort:
- renv->re_TargetRPort = (struct RastPort*)current_tag->ti_Data;
- DBG1("\tRastPort $%08lx", renv->re_TargetRPort);
- rpset = TRUE;
- tag_counter++;
- break;
-
- case TTA_ColorMap:
- renv->re_TargetCMap = (struct ColorMap*)current_tag->ti_Data;
- DBG1("\tColorMap $%08lx", renv->re_TargetCMap);
- cmset = TRUE;
- tag_counter++;
- break;
-
- case TTA_Screen:
- if (!rpset) renv->re_TargetRPort = &((struct Screen*)current_tag->ti_Data)->RastPort;
- if (!cmset) renv->re_TargetCMap = ((struct Screen*)current_tag->ti_Data)->ViewPort.ColorMap;
- DBG1("\tScreen $%08lx", current_tag->ti_Data);
- DBG2("\t[RPort $%08lx, CMap $%08lx]", renv->re_TargetRPort, renv->re_TargetCMap);
- tag_counter++;
- break;
-
- case TTA_Window:
- if (!rpset)renv->re_TargetRPort = ((struct Window*)current_tag->ti_Data)->RPort;
- if (!cmset)renv->re_TargetCMap = ((struct Window*)current_tag->ti_Data)->WScreen->ViewPort.ColorMap;
- DBG1("\tWindow $%08lx", current_tag->ti_Data);
- DBG2("\t[RPort $%08lx, CMap $%08lx]", renv->re_TargetRPort, renv->re_TargetCMap);
- tag_counter++;
- break;
- }
- }
- }
-
- /****** ttrender.library/TT_PutStrTagList ***********************************
- *
- * NAME
- * TT_PutStrTagList -- Renders string into RastPort with local settings.
- *
- * SYNOPSIS
- * success = TT_PutStrTagList (string, taglist)
- * A0 A1
- *
- * BOOL TT_PutStrTagList (UBYTE*, struct TagItem*);
- *
- * success = TT_PutStrTags (string, Tag1, ...)
- *
- * BOOL TT_PutStrTags (UBYTE*, Tag, ...);
- *
- * FUNCTION
- * Renders the string allowing temporary override of current
- * ttrender.library settings, and current RastPort settings. Attributes
- * given in the taglist have local precedence over global
- * ttrender.library settings set by TT_SetModesTagList() call. Check
- * TT_SetModesTagList() docs for a list of tags.
- *
- * INPUTS
- * string - NULL-terminated string to render to.
- *
- * taglist - local attributes valid only in this function call.
- *
- * RESULT
- * TRUE if the string has been rendered.
- *
- * EXAMPLE
- *
- * \* Turn antialias mode on globally *\
- *
- * TT_SetModesTags(TTA_Antialias, TRUE);
- *
- * TT_PutStr("some text"); \* this text will be antialiased *\
- * TT_PutStrTags("another text",
- * TTA_Antialias, FALSE, \* this text won't (locally *\
- * TAG_END); \* switched off) *\
- * TT_PutStr("third text"); \* this text will be antialiased *\
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- * TT_PutStr(), TT_SetModesTagList()
- *
- *****************************************************************************
- *
- */
-
- __saveds BOOL TT_PutStrTagList(struct TTRenderBase *ttb reg(a6), UBYTE *str reg(a0), struct TagItem *taglist reg(a1))
- {
- USELIB(SysBase);
- USELIB_DBG(DOSBase)
- struct RenderEnv local;
-
- DBG("Local TT_PutStrTagList() settings change:");
- CopyMem(&ttb->ttb_RenderEnv, &local, sizeof(struct RenderEnv));
- parse_taglist(ttb, taglist, &local);
- if (local.re_TargetRPort && local.re_TargetCMap)
- {
- tt_putstr(ttb, &local, local.re_TargetRPort->cp_x, local.re_TargetRPort->cp_y, str, FALSE);
- return TRUE;
- }
- return FALSE;
- }
-
- /****** ttrender.library/TT_PutUStrTagList **********************************
- *
- * NAME
- * TT_PutUStrTagList -- Renders 16-bit Unicode string into RastPort with
- * local settings.
- *
- * SYNOPSIS
- * success = TT_PutUStrTagList (string, taglist)
- * A0 A1
- *
- * BOOL TT_PutUStrTagList (UWORD*, struct TagItem*);
- *
- * success = TT_PutUStrTags (string, Tag1, ...)
- *
- * BOOL TT_PutUStrTags (UWORD*, Tag, ...);
- *
- * FUNCTION
- * Renders the 16-bit Unicode string allowing temporary override of
- * current ttrender.library settings, and current RastPort settings.
- * Attributes given in the taglist have local precedence over global
- * ttrender.library settings set by TT_SetModesTagList() call. Check
- * TT_SetModesTagList() docs for a list of tags.
- *
- * INPUTS
- * string - NULL-terminated 16-bit Unicode string to render to.
- *
- * taglist - local attributes valid only in this function call.
- *
- * RESULT
- * TRUE if the string has been rendered.
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- * TT_PutUStr(), TT_SetModesTagList()
- *
- *****************************************************************************
- *
- */
-
- __saveds BOOL TT_PutUStrTagList(struct TTRenderBase *ttb reg(a6), UWORD *str reg(a0), struct TagItem *taglist reg(a1))
- {
- USELIB(SysBase);
- USELIB_DBG(DOSBase)
- struct RenderEnv local;
-
- DBG("Local TT_PutUStrTagList() settings change:");
- CopyMem(&ttb->ttb_RenderEnv, &local, sizeof(struct RenderEnv));
- parse_taglist(ttb, taglist, &local);
- if (local.re_TargetRPort && local.re_TargetCMap)
- {
- tt_putstr(ttb, &local, local.re_TargetRPort->cp_x, local.re_TargetRPort->cp_y, str, TRUE);
- return TRUE;
- }
- return FALSE;
- }
-
- /****** ttrender.library/TT_SetModesTagList *********************************
- *
- * NAME
- * TT_SetModesTagList -- Sets global rendering settings.
- *
- * SYNOPSIS
- * count = TT_SetModesTagList (taglist)
- * A0
- *
- * ULONG TT_SetModesTagList (struct TagItem*);
- *
- * count = TT_SetModesTags (Tag1, ...)
- *
- * ULONG TT_SetModesTags (Tag, ...);
- *
- * FUNCTION
- * Sets global (per library opening) render engine settings. Every
- * following TT_PutStr() / TT_PutUStr() call will use these settings.
- * They can by overriden temporarily however, with TT_PutStrTagList() /
- * TT_PutUStrTagList() calls. Here is a list of attributes:
- *
- * TTA_RastPort - (struct RastPort*) - Destination RastPort for
- * rendering. The library will adhere to this RastPort settings like
- * draw mode, pens, current pen position.
- *
- * TTA_ColorMap - (struct ColorMap*) - ColorMap used to convert pen
- * number to RGB color value.
- *
- * TTA_Screen - (struct Screen*) - useful shortcut for TTA_RastPort and
- * TTA_ColorMap, automatically sets screen ColorMap and screen
- * RastPort.
- *
- * TTA_Window - (struct Window*) - useful shortcut for TTA_RastPort and
- * TTA_ColorMap, automatically sets window ColorMap and window
- * RastPort.
- *
- * TTA_Antialias - (BOOL) - controls antialiasing (on or off).
- *
- * INPUTS
- * taglist - the list of global attributes.
- *
- * RESULT
- * counter - the count of recognized tags.
- *
- * NOTES
- * TTA_RastPort and TTA_ColorMap attributes have precedence over
- * TTA_Screen and TTA_Window ones. It can be useful if one wants to use
- * window/screen ColorMap but separate RastPort. An example:
- *
- * TT_SetModesTags(TTA_Window, win, TTA_RastPort, my_rport, TAG_END);
- *
- * It will set window colormap and 'my_rport' as targets. Note that the
- * precedence is based on tag values, not on tags order. So ordering of
- * the tags is meaningless for the function.
- *
- * BUGS
- *
- * SEE ALSO
- * TT_PutStr(), TT_SetModesTagList()
- *
- *****************************************************************************
- *
- */
-
- __saveds ULONG TT_SetModesTagList(struct TTRenderBase *ttb reg(a6), struct TagItem *taglist reg(a0))
- {
- USELIB_DBG(DOSBase)
-
- DBG("Global settings change:");
- return (parse_taglist(ttb, taglist, &ttb->ttb_RenderEnv));
- }
-
- /****** ttrender.library/TT_GetFontAttrsTagList *****************************
- *
- * NAME
- * TT_GetFontAttrsTagList -- Gets current font attributes (V2).
- *
- * SYNOPSIS
- * count = TT_GetFontAttrsTagList (taglist)
- * A0
- *
- * ULONG TT_GetFontAttrsTagList (struct TagItem*);
- *
- * count = TT_GetFontAttrsTags (Tag1, ...)
- *
- * ULONG TT_GetFontAttrsTags (Tag, ...);
- *
- * FUNCTION
- * Gets current (set by last SetFont() call) font attributes (global
- * metrics mainly). The value of every attribute is written to an ULONG
- * pointed by ti_Data field of the TagItem. Here is a list of attributes:
- *
- * TTFA_Ascender - This is a distance (in pixels) between the baseline
- * and top elements of the font (typically these elements are accents
- * of capital letters). NOTE: many shareware TT fonts have wrong ascen-
- * der value.
- *
- * TTFA_Descender - This is a distance (in pixels) between the baseline
- * and bottom elements of the font (typically in letters 'p', 'q', 'g'
- * etc.). NOTE: many shareware TT fonts have wrong descender value.
- * Descender value is typically negative (as bottom elements usually
- * are placed below the baseline).
- *
- * NOTE: TTFA_Ascender and TTFA_Descender are guarranted to fulfill
- * following formula: ascender - descender = font height.
- *
- * INPUTS
- * taglist - the list of attributes.
- *
- * RESULT
- * counter - the count of recognized tags.
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- * TT_SetFont()
- *
- *****************************************************************************
- *
- */
-
- __saveds ULONG TT_GetFontAttrsTagList(struct TTRenderBase *ttb reg(a6), struct TagItem *taglist reg(a0))
- {
- USELIB(UtilityBase);
- USELIB_DBG(DOSBase)
-
- struct TagItem *current_tag, *tag_pointer = taglist;
- ULONG tag_counter = 0;
-
- DBG("TT_GetFontAttrsTagList()");
-
- while (current_tag = NextTagItem(&tag_pointer))
- {
- switch (current_tag->ti_Tag)
- {
- case TTFA_Ascender:
- *(ULONG*)current_tag->ti_Data = ttb->ttb_Ascender;
- DBG2("\tTTFA_Ascender (%ld) written at %08lx", ttb->ttb_Ascender, current_tag->ti_Data);
- tag_counter++;
- break;
-
- case TTFA_Descender:
- *(ULONG*)current_tag->ti_Data = ttb->ttb_Descender;
- DBG2("\tTTFA_Descender (%ld) written at %08lx", ttb->ttb_Descender, current_tag->ti_Data);
- tag_counter++;
- break;
- }
- }
- return tag_counter;
- }
-
- /****** ttrender.library/TT_StrWidth ****************************************
- *
- * NAME
- * TT_StrWidth -- Gets string width in pixels (V2).
- *
- * SYNOPSIS
- * width = TT_StrWidth(string)
- * A0
- *
- * ULONG TT_StrWidth (UBYTE*);
- *
- * FUNCTION
- * Calculates the pixel width of given string written with current font.
- * Takes kerning into account. String will be mapped to Unicode using
- * "ENV:ttfcodepage" table (see TT_PutStr() docs).
- *
- * INPUTS
- * string - the width of this string will be calculated.
- *
- * RESULT
- * width - the width of the string in pixels.
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- * TT_PutStr(), TT_SetFont()
- *
- *****************************************************************************
- *
- */
-
- __saveds ULONG TT_StrWidth(struct TTRenderBase *ttb reg(a6), UBYTE *string reg(a0))
- {
- return (tt_strwidth(ttb, &ttb->ttb_RenderEnv, string, FALSE));
- }
-
- /****** ttrender.library/TT_UStrWidth ***************************************
- *
- * NAME
- * TT_UStrWidth -- Gets Unicode 16-bit string width in pixels (V2).
- *
- * SYNOPSIS
- * width = TT_UStrWidth(string)
- * A0
- *
- * ULONG TT_UStrWidth (UWORD*);
- *
- * FUNCTION
- * Calculates the pixel width of given 16-bit Unicode string written
- * with current font. Takes kerning into account.
- *
- * INPUTS
- * string - the width of this 16-bit Unicode string will be calculated.
- *
- * RESULT
- * width - the width of the string in pixels.
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- * TT_PutUStr(), TT_SetFont()
- *
- *****************************************************************************
- *
- */
-
- __saveds ULONG TT_UStrWidth(struct TTRenderBase *ttb reg(a6), UWORD *string reg(a0))
- {
- return (tt_strwidth(ttb, &ttb->ttb_RenderEnv, string, TRUE));
- }
-
-